
/**
 *     LinkUtilPlayer.java 
 *
 *       Describes the droptailQueue events, and produces a stream 
 *       summary panel, but makes no attempt to animate them.
 */

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;

import java.text.*;
import java.awt.font.*;
import java.util.*;

import SSF.Net.*;
import SSF.OS.BGP4.*;
import SSF.OS.BGP4.Comm.*;
import SSF.OS.BGP4.Util.*;
import SSF.Util.Streams.*;
import SSF.OS.NetFlow.BytesUtil;

import com.renesys.raceway.views.*;

public class LinkUtilPlayer implements Stream.Player {

    java.text.DecimalFormat fm;

    protected int numHosts; 

    public LinkUtilPlayer() {
	fm = new DecimalFormat();
	fm.setMinimumFractionDigits(3);
	fm.setMaximumFractionDigits(3);
    }

    public void play(Stream.Record rec) {/*noop*/};

    public String toString() {
	return "Link Utilization Stream Player";
    }

    protected Stream stream;

    public void setStream(Stream stream) {
	this.stream = stream;
    }

    //--------------------------------------------------- START, FINISH

    public void start(Stream stream) {
	System.err.println("** LinkUtilPlayer starting");
    }
    public void finish(Stream stream) {
	System.err.println("** LinkUtilPlayer finishing");
    }

    //------------------------------------------------------- DESCRIBE
    
    public AttributedString describe(Stream.Record record) {
	
	int typeid   = record.type_code;
	int srcid    = record.source_code;
	double time  = record.timestamp;
	byte[] buf   = record.bytes;
	int bindex   = record.offset;
	int length   = record.length;
	
        if (!stream.getRecordTypeString(typeid).equals
	    ("SSF.Net.QueueRecord_2")) 
	    return null; // let someone else render it
        
	int sumct = BytesUtil.bytesToInt(buf,bindex+0);
	int sumdrop = BytesUtil.bytesToInt(buf,bindex+4);
	int ct = BytesUtil.bytesToInt(buf,bindex+8);
	int drop = BytesUtil.bytesToInt(buf,bindex+12);

	String src_nhi = stream.getRecordSourceString(srcid);
	
        Color newColor = new Color(0x33,0x33,0x33); // black
	if (drop>ct) newColor = new Color(0x33,0,0); // red
	if (drop==0) newColor = new Color(0,0x33,0); // green
	String msg = (fm.format(time)+" "+src_nhi+
	    " sumct="+sumct+" sumdrop="+sumdrop+
	    " ct="+ct+" drop="+drop);
	AttributedString ret = new AttributedString(msg);
	ret.addAttribute(TextAttribute.FOREGROUND, newColor);
	return ret;
    }

    //---------------------------------------------------  CONTROLS 

    private Component controls = null;
    public synchronized Component getControls() {
	if (null==controls) 
	    controls = new JScrollPane(new LinkUtilPlayerControls());
	return controls;
    }

    private class LinkUtilPlayerControls extends JPanel {
	public LinkUtilPlayerControls() {
	    setForeground(Color.black);
	    setBackground(Color.white);
	    int ct =0;
	    int ifct =0;
	    long pkts =0;
	    long drop =0;

	    HashMap table = new HashMap();
	    for (Stream.Iterator i = stream.iterator();
		 i.hasMoreRecords();) {
		// Make one pass to identify options that 
		// appear in this stream.
		Stream.Record record = i.nextRecord();
		ct++;
		
		int typeid   = record.type_code;
		int srcid    = record.source_code;
		byte[] buf   = record.bytes;
		int bindex   = record.offset;

		if (stream.getRecordTypeString(typeid).equals
		    ("SSF.Net.QueueRecord_2")) {
		    ct++;
		    String src_nhi = stream.getRecordSourceString(srcid);
		    if (null==table.get(src_nhi)) {
			ifct++;
			table.put(src_nhi,src_nhi);
		    }
		    pkts += BytesUtil.bytesToInt(buf,bindex+8);
		    drop += BytesUtil.bytesToInt(buf,bindex+12);
		}
	    }


	    setLayout(new BorderLayout());
	    add(new JTextField("Summary: "+ct+" Records, "+ifct+" Hosts, "+
			       pkts+" Packets, "+drop+" Drops"),
		BorderLayout.CENTER);

	    numHosts = ifct;
	}
    }
}
